/**
 * Created by ecervetti on 28/02/14.
 */


Univers = function(ihm)  {
    this.init(ihm);
};

Univers.prototype = {
    iPointerIHM : 0, //premiere case en bas à gauche
    jPointerIHM : 0, //premiere case en bas à gauche
    data : null ,
    pente: 0,
    lastCreatedX : -1 ,
    oldestCreatedX : - 1 ,
    selectedCol : -1 ,
    deviationSeed : 0.7 ,
    isRecord: false ,
    isOwnRecord: false ,
    /**
     * @type {Duck}
     */
    duck : null ,
    g : 9.8/(1000*1000) ,
    ignition : false , //uniquement pour lancer le redémarrage du jeu
    tuto : true ,
    /**
     * @type {GameIhm}
     */
    ihm : null ,
    init: function(ihm) {
        var thisUnivers = this  ;
        this.ihm = ihm ;
        this.ignition = true ;
        ihm.univers = this ;
        thisUnivers.pente = 0.9 ;
        thisUnivers.newGame();
    },

    spriteInfoProvider : function(i,j) {
        var thisUnivers = this ;
        i = Math.floor(i);
        j = Math.floor(j);

        while(!thisUnivers.data[i]){
            //console.log(i+" n'est pas connue, je demande une creation de terrain jusqua 1  + "+i);
            thisUnivers.newTerrainTo(i);
        }
        if(thisUnivers.data[i].height >= j ) {
            return thisUnivers.data[i].type ;
        } else {
            return 0 ;
        }
    },

    /**
     *
     * @param iMin limite gauche du terrain de jeu à créer
     * @param iMax limite droite du terrain de jeu à créer
     * @param jMin hauteur correspondante à la limite gauche
     */
    createTerrain : function(iMin,iMax,jMin) {
        var thisUnivers = this ;

        thisUnivers.basicLooperHorizontal(thisUnivers.oldestCreatedX,thisUnivers.iPointerIHM-1,function(i){
            delete thisUnivers.data[i];
        });
        thisUnivers.oldestCreatedX = thisUnivers.iPointerIHM ;

        thisUnivers.basicLooperHorizontal(iMin,iMax,function(i){
            if(!thisUnivers.oldestCreatedX) {
                thisUnivers.oldestCreatedX = i ;
            }
            //hauteur moyenne attendue
            thisUnivers.lastCreatedX = i  ;
            var height = 1+Math.round(jMin + (i-iMin)*thisUnivers.pente) ;
            //Déviation
            height += Math.round((Math.random()-0.5)*thisUnivers.deviationSeed*thisUnivers.ihm.discrWidth*thisUnivers.pente);
            thisUnivers.data[i]= new Colonne(height, 1 );
        });
    },

    basicLooperHorizontal: function(iMin,iMax,closCall)  {
        //var thisIHM = this ;
        for(var i=iMin;i<=iMax;i++) {
                closCall(i);
        }
    },

    newTerrainTo : function(i) {
        var thisUnivers = this ;
            thisUnivers.createTerrain(
                thisUnivers.lastCreatedX+1,
                i+1 ,
                this.jPointerIHM+thisUnivers.pente*(thisUnivers.lastCreatedX+1-thisUnivers.iPointerIHM)
            );
    },

    physics : function(timeIntervallSinceLastCalc) {
        var thisUnivers = this ;
        if(thisUnivers.ignition) {
            thisUnivers.newGame();
        }

        var oldIPointer = thisUnivers.iPointerIHM ;

        thisUnivers.duck.physics(timeIntervallSinceLastCalc);



        var distance = thisUnivers.duck.i - thisUnivers.iPointerIHM ;
        if(distance <= 0) {
            //Si le canard a dépassé la gauche de l'écran, on rattrape illico
            thisUnivers.iPointerIHM = thisUnivers.duck.i ;
        } else {
            //Plus le canard est loin du bord gauche visible, plus vite on va décaler la caméra sur la droite  //Le décalage maximal est donc de distance    //on va diviser distance par quelque chose compris entre 1 et l'infni. infini à gauche, 1 à droite             //distanceMax/distance va donner 1 si on s'approche du bord droit de l'écran, infini vers le gauche. On met au pif à une puissance pour dramatiser l'effet
            thisUnivers.iPointerIHM = thisUnivers.iPointerIHM + distance/ Math.pow(thisUnivers.ihm.discrWidth / distance,4 );
        }
        var translationX = thisUnivers.iPointerIHM-oldIPointer ;

        var translationY = thisUnivers.pente * translationX ;

        thisUnivers.jPointerIHM+=translationY;

        if( ! thisUnivers.isRecord && thisUnivers.jPointerIHM > 10 && (Math.floor(thisUnivers.jPointerIHM)>  thisUnivers.ihm.bestscore) ) {
            thisUnivers.isRecord = true ;
            thisUnivers.ihm.alerteNiveau();
        }
        if( ! thisUnivers.isOwnRecord && thisUnivers.jPointerIHM > 10 && ( Math.floor(thisUnivers.jPointerIHM)>  thisUnivers.ihm.bestpersonalscore ) ) {
            thisUnivers.isOwnRecord = true ;
            thisUnivers.ihm.alerteNiveau();
        }

        //X et Y sont renvoyés positifs
        return new Coords(translationX,translationY) ;
    },


    newGame : function() {
        var thisUnivers = this ;
        thisUnivers.iPointerIHM = 0 ;
        thisUnivers.jPointerIHM = 0 ;
        thisUnivers.data={};
        thisUnivers.lastCreatedX = -1 ;
        thisUnivers.oldestCreatedX = -1 ;
        thisUnivers.selectedCol = -1 ;
        thisUnivers.nextLevel = 50 ;
        thisUnivers.createTerrain(
            thisUnivers.iPointerIHM,
            thisUnivers.iPointerIHM+thisUnivers.ihm.discrWidth,
            thisUnivers.jPointerIHM
        );
        thisUnivers.duck = new Duck(thisUnivers);
        thisUnivers.ignition = false ;
        thisUnivers.ihm.reset();
    },


    effondrementColonne : function(i,f) {
        var thisUnivers = this ;
        thisUnivers.ihm.animation = true ;
        if(thisUnivers.duck.j >= thisUnivers.jPointerIHM  ){
            thisUnivers.data[i].height -- ;
            thisUnivers.duck.j -- ;
            setTimeout(function(){
                thisUnivers.effondrementColonne(i,f);
            },40);
        } else {

            thisUnivers.ihm.animation = false ;
            f();
        }
    },

    endJourney : function() {
      var thisUnivers = this ;
        var audio = new Audio('duckurgence.mp3');
        audio.play();
        thisUnivers.effondrementColonne(thisUnivers.duck.i,function(){
            thisUnivers.ihm.messageEnd(Math.floor(thisUnivers.jPointerIHM));
            thisUnivers.ignition = true ;
        });
    },

    changeCol : function(i) {

        var thisIHM = this ;
        if(thisIHM.data[thisIHM.selectedCol]) {
            thisIHM.data[thisIHM.selectedCol].type = 1 ;
        }
        thisIHM.selectedCol = i ;
        thisIHM.data[i].type = 2 ;
    }

};